home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 134_01 / casm2.c < prev    next >
Text File  |  1985-08-19  |  24KB  |  945 lines

  1. /*
  2.     CASM.C    -- written by Leor Zolman, 2/82
  3.     Modified for v1.50 11/14/82
  4.  
  5.     Modified for use with CTOA CRL-to-ASM postprocessor 11/2/83 K. Kenny
  6.     Modified to allow conditional assembly of relocatable code
  7.         11/15/83 K. Kenny.
  8.  
  9.     CP/M ASM preprocessor: renders MAC.COM and CMAC.LIB unnecessary.
  10.  
  11.     See the CASM Appendix in the User's Guide for complete information.
  12.  
  13.     Compile and link with:
  14.  
  15.         cc casm.c -o -e5000
  16.  
  17.         l2 casm
  18.     (or)    clink casm
  19. */
  20.  
  21. #include <bdscio.h>
  22.  
  23. #define TITLE "BD Software CRL-format ASM Preprocessor v1.50+mods\n"
  24.  
  25.  
  26. /*
  27.  *    Customizable definitions:
  28.  */
  29.  
  30. #define DEFUSER    "0/"        /* default user area for include files    */
  31.                 /* make this a null string for "current" */
  32.  
  33. #define DEFDISK "A:"        /* default disk for include files    */
  34. #define CASMEXT    ".CSM"        /* extension on input files     */
  35. #define ASMEXT    ".ASM"        /* extension on output files    */
  36. #define SUBFILE "A:$$$.SUB"    /* Submit file to erase on error. To not */
  37.                 /* erase any, use a null string ("")     */
  38.  
  39. #define CONTROL_C 3        /* Abort character */
  40. #define    EQUMAX    500        /* maximum number of EQU ops    */
  41. #define FUNCMAX    100        /* maximum number of functions  */
  42. #define NFMAX    100        /* maximum number of external
  43.                    functions in one function     */
  44. #define LABMAX    150        /* max number of local labels in one func */
  45. #define TXTBUFSIZE 2000        /* max # of chars for labels and needed
  46.                    function names for a single function    */
  47. #define CONDBUFSIZE 2000    /* max # of chars of conditional assembly 
  48.                    pseudo-ops per function */
  49.  
  50. /*
  51.  *    End of customizable section
  52.  */
  53.  
  54. #define DIRSIZE    512        /* max # of byte in CRL directory     */
  55. #define TPALOC    0x100        /* base of TPA in your system     */
  56.  
  57.         /* Global data used throughout processing
  58.            of the input file:            */
  59.  
  60. char    fbuf[BUFSIZ];        /* I/O buffer for main input file    */
  61. char    incbuf[BUFSIZ];        /* I/O buffer for included file     */
  62. char    obuf[BUFSIZ];        /* I/O buffer for output file        */
  63.  
  64. char    *cbufp;            /* pointer to currently active input buf */
  65. char    *cfilnam;        /* pointer to name of current input file */
  66. char    nambuf[30],        /* filenames for current intput */
  67.     nambuf2[30],        /* and output files.        */
  68.     onambuf[30];
  69.  
  70. char    *equtab[EQUMAX];    /* table of absolute symbols    */
  71. int    equcount;        /* # of entries in equtab    */
  72.  
  73. char    *fnames[FUNCMAX];    /* list of functions in the source file */
  74. int    fcount;            /* # of entries in fnames        */
  75.  
  76. int    lino,savlino;        /* line number values used for error     */
  77.                 /* reporting.                */
  78.  
  79. char    doingfunc;        /* true if currently processing a function */
  80.  
  81. char    errf;            /* true if an error has been detected    */
  82. char    verbose;        /* true to insert wordy comments in output */
  83. char    careful;        /* true to detect old CMAC.LIB macros   */
  84. char    blankflag;        /* true if last line processed was null */
  85.  
  86.         /* Global data used during the processing of a
  87.            single function in the source file:        */
  88.  
  89. char    *nflist[NFMAX];        /* list of needed functions for a function */
  90. int    nfcount;        /* number of entries in nflist    */
  91.  
  92. struct {
  93.     char *labnam;        /* name of function label */
  94.     char defined;        /* whether it has been defined yet */
  95. } lablist[LABMAX];
  96.  
  97. int    labcount;        /* number of local labels in a function */
  98.  
  99. char    txtbuf[TXTBUFSIZE],    /* where text of needed function names    */
  100.     *txtbufp;        /* and function labels go        */
  101.  
  102. char    condbuf[CONDBUFSIZE];    /* where conditional assembly directives go */
  103. union {
  104.     int * ci;
  105.     char * cb;
  106.     } condptr;
  107.  
  108. char     linbuf[150],        /* text line buffers    */
  109.     linsav[150],
  110.     workbuf[150],
  111.     undrbuf[150],
  112.     pbuf[150], *pbufp;
  113.  
  114. char    *cfunam;        /* pointer to name of current function */
  115. int    relblc;            /* relocation object count for a function */
  116.  
  117. char    pastnfs;        /* true if we've passed all needed function */
  118.                 /* declarations ("external" pseudo ops)        */
  119.  
  120. int    argcnt;            /* values set by the "parse_line" function */
  121. char    *label,
  122.     *op,
  123.     *argsp,
  124.     *args[40];
  125.  
  126. char     *gpcptr;        /* general-purpose text pointer    */
  127.  
  128. /*
  129.  * Open main input file, open output file, initialize needed globals
  130.  * and process the file:
  131.  */
  132.  
  133. main(aarghc,aarghv)
  134. char **aarghv;
  135. {
  136.     int i,j,k;
  137.     char c, *inpnam, *outnam;
  138.  
  139.     puts(TITLE);
  140.  
  141.     initequ();        /* initialize EQU table with reserved words */
  142.     fcount = 0;        /* haven't seen any functions yet */
  143.     doingfunc = FALSE;    /* not currently processing a function */
  144.     errf = FALSE;        /* no errors yet */
  145.     verbose = careful = FALSE;
  146.     inpnam = outnam = NULL;        /* haven't seen any names yet */
  147.     blankflag = FALSE;    /* haven't just processed a null line */
  148.     
  149.     while (--aarghc) 
  150.     {
  151.         ++aarghv;        /* bump to next arg text */
  152.         if (**aarghv == '-')
  153.         {
  154.             switch(c = aarghv[0][1])
  155.             {
  156.             case 'F':
  157.                 careful = 1;
  158.                 break;
  159.  
  160.             case 'C':
  161.                 verbose = 1;
  162.                 break;
  163.  
  164.             case 'O':
  165.                 if (aarghv[0][2])
  166.                     outnam = &aarghv[0][2];
  167.                 else if (--aarghc)
  168.                     outnam = *++aarghv;
  169.                 else goto usage;
  170.                 break;
  171.  
  172.             default: goto usage;
  173.             }
  174.         }
  175.         else
  176.             inpnam = *aarghv;
  177.     }
  178.  
  179.     if (!inpnam) {
  180.   usage:    puts("Usage:\tcasm [-f] [-c] [-o <name>] <filename>\n");
  181.         puts("-F: flag old CMAC.LIB macros if spotted\n");
  182.         puts("-C: don't strip comments from input and output\n");
  183.         puts("-O <name>: Call the output file <name>.ASM\n");
  184.         exit();
  185.     }
  186.  
  187.                 /* set up filenames with proper extensions: */
  188.     for (i = 0; (c = inpnam[i]) && c != '.'; i++)
  189.         nambuf[i] = c;
  190.     nambuf[i] = '\0';
  191.  
  192.     strcpy(onambuf, outnam ? outnam : nambuf);
  193.     strcat(nambuf,CASMEXT);        /* input filename */
  194.     cbufp = fbuf;            /* buffer pointer */
  195.     cfilnam = nambuf;        /* current filename pointer */
  196.     if (fopen(cfilnam,cbufp) == ERROR)
  197.         exit(printf("Can't open %s\n",cfilnam));
  198.  
  199.     if (!hasdot(onambuf))
  200.         strcat(onambuf,ASMEXT);        /* output filename */
  201.     if (fcreat(onambuf,obuf) == ERROR)
  202.         exit(printf("Can't create %s\n",onambuf));
  203.  
  204.                     /* begin writing output file */
  205.     fprintf2(obuf,"\nTPALOC\t\tEQU\t%04xH\n",TPALOC);
  206.  
  207.     fprintf2(obuf,"\nSYS$EXTFLAG\tSET\t0\n");
  208.     fprintf2(obuf,"SYS$EXTADDR\tSET\t0\n");
  209.     fprintf2(obuf,"SYS$EXTSIZE\tSET\t0\n");
  210.     fprintf2(obuf,"\t\tORG\tTPALOC+0205H\n\n");
  211.  
  212.     lino = 1;            /* initialize line count */
  213.  
  214.     while (get_line()) {        /* main loop */
  215.         if (kbhit() && getchar() == CONTROL_C)
  216.             abort("Aborted by ^C\n");
  217.         process_line();        /* process lines till EOF */
  218.         lino++;
  219.     }
  220.  
  221.     if (doingfunc)            /* if ends inside a function, error */
  222.         abort("File ends, but last function is unterminated\n");
  223.  
  224.     if (errf)
  225.     {
  226.         puts("Fix those errors and try again...");
  227.         unlink(onambuf);
  228.         if (*SUBFILE) 
  229.             unlink(SUBFILE);
  230.     }
  231.     else
  232.     {
  233.                             /* end of functions */
  234.         fputs2("\nEND$CRL\t\tEQU\t$-TPALOC\n",obuf);
  235.         fputs2("SECTORS$ EQU ($-TPALOC)/256+1 ;USE FOR \"SAVE\" !.\n",
  236.             obuf);
  237.         putdir();            /* now put out CRL directory */
  238.         fputs2("\t\tEND\n",obuf);    /* end of ASM file */
  239.         putc(CPMEOF,obuf);        /* CP/M EOF character */
  240.         fclose(cbufp);            /* close input file */
  241.         fclose(obuf);            /* close output file */
  242.         printf("%s is ready to be assembled.\n",onambuf);
  243.     }
  244. }
  245.  
  246. /*
  247.  * Get a line of text from input stream, and process
  248.  * "include" ops on the fly:
  249.  */
  250.  
  251. int get_line()
  252. {
  253.     int i;
  254.  
  255. top:    if (!fgets(linbuf,cbufp)) {        /* on EOF: */
  256.         if (cbufp == incbuf) {        /* in an "include" file? */
  257.             fabort(cbufp->_fd);        /* close the file */
  258.             cbufp = fbuf;        /* go back to mainline file */
  259.             cfilnam = nambuf;
  260.             lino = savlino + 1;
  261.             return get_line();
  262.         }
  263.         else return NULL;
  264.     }
  265.  
  266.     if (!verbose)                /* strip commments, default */
  267.     {
  268.         for (i = 0; linbuf[i]; i++)
  269.         {
  270.             if (linbuf[i] == ';')
  271.             {
  272.                 while (i && isspace(linbuf[i-1]))
  273.                     i--;
  274.                 if (!i && blankflag)
  275.                 {
  276.                     lino++;
  277.                     goto top;
  278.                 }
  279.                 strcpy(&linbuf[i], "\n");
  280.                 blankflag = TRUE;
  281.                 break;
  282.             }
  283.             if (linbuf[i] == '\'' || linbuf[i] == '"')
  284.                 break;
  285.         }
  286.         if (!linbuf[i])
  287.             blankflag = FALSE;        
  288.     }
  289.  
  290.     parse_line();                /* not EOF. Parse line */
  291.     if (streq(op,"INCLUDE")  ||        /* check for file inclusion */
  292.         streq(op,"MACLIB")) {
  293.         if (cbufp == incbuf)        /* if already in an include, */
  294.          abort("Only one level of inclusion is supported"); /* error */
  295.         if (!argsp)
  296.          abort("No filename specified");
  297.         cbufp =